<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        class EventEmitter {
            constructor() {
                this.events = {}
                this.maxListeners = 10
                this.taskQueue = [];
                this.isProcessing = false;
            }
            /**
             * 发布事件
             * @param {string} eventName 事件名称
             * @param {...any} args 传递给监听函数的参数
             * @returns {boolean} 是否有监听器被调用
            */
           async emit(eventName, ...args) {
                this.taskQueue.push({ eventName, args });
                if (!this.isProcessing) {
                    this.isProcessing = true
                    while (this.taskQueue.length > 0) {
                        const task = this.taskQueue.shift();
                        await this.processEvent(task.eventName, ...task.args)
                    }
                    this.isProcessing = false
                }
           }
           async processEvent(eventName, ...args) {
                const callbacks = this.events[eventName]
                if (callbacks) {
                    // 并行执行监听器
                    await Promise.all(callbacks.map(cb => Promise.resolve().then(() => cb(...args))))
                }
           }
            /**
             * 订阅事件
             * @param {string} eventName 事件名称
             * @param {Function} listener 监听函数
             * @returns {this} 返回实例本身以支持链式调用
             */
            on(eventName, listener) {
                if (typeof listener !== 'function') {
                    throw new TypeError('Listener must be a function');
                }
                if (!this.events[eventName]) {
                    this.events[eventName] = []
                }

                // 检查监听器数量是否超过限制
                if (this.events[eventName].length >= this.maxListeners) {
                    console.warn(`Possible EventEmitter memory leak detected. 
                    ${this.events[eventName].length} ${eventName} listeners added. 
                    Use emitter.setMaxListeners() to increase limit`);
                }
                this.events[eventName].push(listener)
                return this
            }
            /**
             * 取消订阅
             * @param {string} eventName 事件名称
             * @param {Function} listener 要移除的监听函数
             * @returns {this} 返回实例本身以支持链式调用
             */
            off (eventName, listener) {
                if (!this.events[eventName]) {
                    return this
                }
                if (typeof listener === 'function') {
                    this.events[eventName] = this.events[eventName].filter(l => l !== listener)
                } else {
                    // 如果没有提供listener，移除该事件的所有监听器
                    delete this.events[eventName]
                }
                return this
            }
            /**
             * 一次性订阅
             * @param {string} eventName 事件名称
             * @param {Function} listener 监听函数
             * @returns {this} 返回实例本身以支持链式调用
             */
            once(eventName, listener) {
                if (typeof listener !== 'function') {
                    throw new TypeError('Listener must be a function');
                }
                const onceWrapper = (...args) => {
                    listener.apply(this, args)
                    this.off(eventName, onceWrapper)
                }

                // 保存原始监听器的引用，以便可以移除
                onceWrapper.listener = listener
                return this.on(eventName, onceWrapper);
            }
            /**
             * 获取所有事件名称
             * @returns {Array<string>} 事件名称数组
             */
            eventNames() {
                console.log(this)
                return Object.keys(this.events)
            }
            /**
             * 获取某个事件的监听器数量
             * @param {string} eventName 事件名称
             * @returns {number} 监听器数量
             */
            listenerCount(eventName) {
                const listeners = this.events[eventName]
                return listeners ? listeners.length : 0
            }
            /**
             * 移除所有监听器
             * @param {string} [eventName] 可选，指定要移除的事件
             * @returns {this} 返回实例本身以支持链式调用
             */
            removeAllListeners(eventName) {
                if (eventName) {
                    delete this.events[eventName]
                } else {
                    this.events = {}
                }
                return this
            }
             /**
             * 设置最大监听器数量
             * @param {number} n 最大监听器数量
             * @returns {this} 返回实例本身以支持链式调用
             */
            setMaxListeners(n) {
                if (typeof n !== 'number' || n < 0) {
                throw new TypeError('n must be a positive number');
                }
                this.maxListeners = n;
                return this;
            }
        }
        
        const emitter = new EventEmitter();

        // 基本订阅和发布
        emitter.on('data', (data) => {
            console.log('Received data:', data);
        });

        emitter.emit('data', { message: 'Hello World' });
        function logMessage(msg) {
            console.log('Message:', msg);
        }
        emitter.on('message', logMessage);
        emitter.emit('message', 'First message');
        emitter.off('message', logMessage);
        emitter.emit('message', 'Second message'); // 不会触发

        emitter.once('hi', msg => console.log('Hi:', msg));

        emitter.emit('hi', '第一次'); // 触发
        emitter.emit('hi', '第二次'); // 不会再触发
        console.log(emitter.eventNames())
        console.log(emitter.listenerCount('hi'))
    </script>
</body>
</html>